package gui;

import java.util.LinkedList;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import core.AbstractMusicLibrary;
import core.Song;
import core.VirtualMusicLibrary;
import events.LibraryChangeEvent;
import events.LibraryListener;

public class SongTable implements TableModel, LibraryListener {

	private static final String[] columns = new String[] { "Title", "Artist",
			"Album", "Time", "Genre" };

	private final LinkedList<TableModelListener> listeners = new LinkedList<TableModelListener>();
	private AbstractMusicLibrary data;

	public SongTable() {
		data = new VirtualMusicLibrary();
		data.addLibraryListener(this);
	}

	public AbstractMusicLibrary getLibrary() {
		return data;
	}

	public void setSource(AbstractMusicLibrary lib) {
		if (data != null) {
			data.removeLibraryListener(this);
		}
		data = lib;
		TableModelEvent event = new TableModelEvent(this);
		for (TableModelListener l : listeners) {
			l.tableChanged(event);
		}
		lib.addLibraryListener(this);
	}

	@Override
	public void addTableModelListener(TableModelListener l) {
		if (listeners.contains(l) == false)
			listeners.add(l);
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		return String.class;
	}

	@Override
	public int getColumnCount() {
		return columns.length;
	}

	@Override
	public String getColumnName(int columnIndex) {
		return columns[columnIndex];
	}

	@Override
	public int getRowCount() {
		return data.getNumSongs();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Song song = data.getSongAt(rowIndex);
		if (song == null)
			return null;
		if (columnIndex == 0)
			return song.getTitle();
		else if (columnIndex == 1)
			return song.getArtist();
		else if (columnIndex == 2)
			return song.getAlbum();
		else if (columnIndex == 3)
			return song.getTotalTime();
		else if (columnIndex == 4)
			return song.getGenre();
		else
			throw new RuntimeException("Value out of range.");
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return false;
	}

	@Override
	public void removeTableModelListener(TableModelListener l) {
		listeners.remove(l);
	}

	@Override
	public void setValueAt(Object value, int rowIndex, int columnIndex) {
		Song song = data.getSongAt(rowIndex);
		String val = value.toString();
		if (columnIndex == 0)
			song.setTitle(val);
		else if (columnIndex == 1)
			song.setArtist(val);
		else if (columnIndex == 2)
			song.setAlbum(val);
		else if (columnIndex == 4)
			song.setGenre(val);
		else
			throw new RuntimeException("Value out of range.");
	}

	@Override
	public void libraryChanged(LibraryChangeEvent e) {
		TableModelEvent event = new TableModelEvent(this);
		for (TableModelListener l : listeners) {
			l.tableChanged(event);
		}
	}
}
